<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="https://fav.farm/🛰️" />
    <title>Custom element (remote) • Remote DOM</title>
  </head>

  <body>
    <div id="root">
      <ui-button primary>Clicked 0 times</ui-button>
    </div>

    <script type="module">
      import {RemoteElement} from '@remote-dom/core/elements';

      // We need to define our `ui-button` element so it can be synchronized
      // with the host environment.
      //
      // For full details on defining remote elements, see the documentation
      // for `@remote-dom/core/elements`:
      // https://github.com/Shopify/remote-dom/tree/main/packages/core#elements
      class UIButton extends RemoteElement {
        static get remoteAttributes() {
          return ['primary'];
        }

        static get remoteEvents() {
          return {
            click: {
              dispatchEvent(detail) {
                console.log(`Event detail: `, detail);
              },
            },
          };
        }
      }

      customElements.define('ui-button', UIButton);
    </script>

    <script type="module">
      // To make this example dynamic, we’ll add an event listener to the button
      // that updates the button’s text content and removes the `primary` attribute
      let count = 0;
      const button = document.querySelector('ui-button');

      button.addEventListener('click', () => {
        count += 1;

        button.textContent = `Clicked ${count} ${
          count === 1 ? 'time' : 'times'
        }`;

        if (count === 5) {
          button.removeAttribute('primary');
        }
      });
    </script>

    <script type="module">
      import {RemoteMutationObserver} from '@remote-dom/core/elements';
      import {ThreadNestedIframe} from '@quilted/threads';

      const root = document.querySelector('#root');

      // We use the `@quilted/threads` library to create a “thread” for our iframe,
      // which lets us communicate over `postMessage` without having to worry about
      // most of its complexities.
      //
      // This block exposes the `render` method that was used by the host application,
      // in `index.html`. We receive the `RemoteConnection` object, and start synchronizing
      // changes to the `<div id="root">` element that contains our UI.
      new ThreadNestedIframe({
        exports: {
          async render(connection) {
            // We use the `RemoteMutationObserver` class, which extends the native DOM
            // `MutationObserver`, to send any changes to a tree of DOM elements over
            // a `RemoteConnection`.
            const observer = new RemoteMutationObserver(connection);
            observer.observe(root);
          },
        },
      });
    </script>
  </body>
</html>
